package org.example.springgobang.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.springgobang.game.Matcher;
import org.example.springgobang.game.RoomManager;
import org.example.springgobang.model.MatchRequest;
import org.example.springgobang.model.MatchResponse;
import org.example.springgobang.game.OnlineUserManager;
import org.example.springgobang.model.Room;
import org.example.springgobang.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Slf4j
@Component
public class MatchAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Autowired
    private RoomManager roomManager;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        /*
        1、先获取到当前用户的身份信息(进入游戏大厅之中，即建立连接)
        (User)session.getAttributes().get("user") 之所以我们可以直接这样
        是因为在前面  registry.addInterceptors(new HttpSessionHandshakeInterceptor());
        这一步实现了将 HttpSession 中的 Attribute 都给拿到 WebSocketSession之中
          */

        /*如果之前用户根本没有进行过登录操作，直接通过其他url 比如 /game_hall.html 这些url来访问游戏大厅
            就会出现 user 为 null 可能会出现空指针异常*/
        try {
            User user=(User)session.getAttributes().get("user");
            //2、判断该用户是否已经在别的地方实现了登录
            if(onlineUserManager.getGameHall(user.getUserId())!=null||
            onlineUserManager.getGameRoom(user.getUserId())!=null){
                MatchResponse response=new MatchResponse();
                response.setOk(true);
                response.setReason("您已在别处实现登录，禁止多开!!");
                response.setMessage("RepeatedConnection");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                //session.close();
                return;
            }

            //3、拿到身份信息，把玩家设置为在线状态
            onlineUserManager.enterGameHall(user.getUserId(),session);
            log.info("玩家"+user.getUsername()+"已经成功登录游戏大厅");
        }catch (NullPointerException e) {
            //e.printStackTrace();
            //此时抛出空指针异常，说明当前用户身份信息为空，用户未登录
            //把当前用户尚未登录这个信息抛回去
            log.info("[MatchAPI]当前玩家未登录");
            MatchResponse response=new MatchResponse();
            response.setOk(false);
            response.setReason("尚未完成登录操作！不能进行后续匹配操作");
            //TextMessage 相当于一个 文本格式的 WebSocket 数据包
            // objectMapper.writeValueAsString(response) 是转换成字符串
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //实现处理开始匹配信息和处理停止匹配信息

        User user=(User)session.getAttributes().get("user");
        //获取数据载荷
        String payload=message.getPayload().toString();
        MatchRequest request=objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse response=new MatchResponse();
        if(request.getMessage().equals("startMatch")){
            //开始匹配 将玩家放入匹配队列
            matcher.add(user);
            //放入匹配队列之后，就可以返回一个响应给客户端
            response.setOk(true);
            response.setMessage("startMatch");
        }else if(request.getMessage().equals("stopMatch")){
            matcher.remove(user);
            response.setOk(true);
            response.setMessage("stopMatch");
        }else if(request.getMessage().equals("startAIMatch")){
            // 创建一个AI玩家
            User aiPlayer = new User();
            aiPlayer.setUserId(-1);  // 使用特殊ID标识AI
            aiPlayer.setUsername("AI玩家");

            // 创建房间
            Room room = new Room();
            room.setAIGame(true);  // 标记为AI对战
            room.setPlayer1(user);
            room.setPlayer2(aiPlayer);
            room.setWhiteUser(user.getUserId());  // 让真实玩家先手

            // 添加到房间管理器
            roomManager.add(room, user.getUserId(), aiPlayer.getUserId());
            response.setOk(true);
            response.setMessage("startAIMatch");
        }else {
            //非法
            response.setOk(false);
            response.setReason("非法的匹配操作");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }


    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            User user=(User)session.getAttributes().get("user");
            WebSocketSession tmpSession= onlineUserManager.getGameHall(user.getUserId());
            if(tmpSession == session){
                onlineUserManager.exitGameHall(user.getUserId());
            }
            //如果玩家正在匹配中 断开了连接 也应该移除队列
            matcher.remove(user);
        }catch (NullPointerException e) {
            e.printStackTrace();
            log.info("服务器出错");
//            MatchResponse response=new MatchResponse();
//            response.setOk(false);
//            response.setReason("尚未完成登录操作！不能进行后续匹配操作");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            User user=(User)session.getAttributes().get("user");
            //判断当前要下线的用户与之前在哈希表储存的用户是否为同一个对象
            WebSocketSession tmpSession= onlineUserManager.getGameHall(user.getUserId());
            if(tmpSession == session){
                onlineUserManager.exitGameHall(user.getUserId());
            }
            matcher.remove(user);
        }catch (NullPointerException e) {
            log.info("当前玩家未登录");
            //e.printStackTrace();
        }
    }

}
